package userController

import (
	"myRbac/models"
	"myRbac/utils"
	"myRbac/utils/jwt"
	"net/http"

	"github.com/gin-gonic/gin"
)

type LoginAbout struct{}

// @Summary 用户注册
// @Description 输入账号密码以及验证码注册
// @Tags 注册登录
// @Accept json
// @Produce json
// @Param userInfo body models.LoginParams true "用户信息"
// @Success 200 {object} models.AddResult "注册成功"
// @Failure 404 {object} models.ErrorResult "请求失败"
// @Failure 403 {object} models.ErrorResult "验证码错误"
// @Failure 402 {object} models.AddResult "用户已存在"
// @Router /register [post]
func (l LoginAbout) Register(ctx *gin.Context) {
	// user := &models.User{}
	var params models.LoginParams
	// 绑定json数据
	if err := ctx.ShouldBindJSON(&params); err != nil {
		ctx.JSON(http.StatusOK, &models.ErrorResult{
			Msg:    "传输失败",
			Code:   "400",
			Result: err,
		})
		return
	}
	// 先校验验证码对不对
	if !utils.CaptVerify(params.Id, params.Code) {
		ctx.JSON(http.StatusOK, &models.ErrorResult{
			Msg:    "验证码错误",
			Code:   "400",
			Result: nil,
		})
		return
	}
	// 查询相同用户
	user := &models.User{}
	models.DB.Where("account=?", params.Account).First(&user)
	if user.Id != 0 {
		ctx.Abort()
		ctx.JSON(http.StatusOK, &models.AddResult{
			Msg:    "用户名已存在",
			Code:   "400",
			Result: 0,
		})
		return
	}
	// 加密密码
	user.Password = utils.Sha256(params.Password)
	user.Username = params.Account
	result := models.DB.Model(&models.User{}).Create(&user)
	if result.RowsAffected != 1 {
		ctx.JSON(http.StatusOK, &models.AddResult{
			Msg:    "注册失败",
			Code:   "400",
			Result: result.RowsAffected,
		})
	} else {
		ctx.JSON(http.StatusOK, &models.AddResult{
			Msg:    "注册成功",
			Code:   "200",
			Result: result.RowsAffected,
		})
	}
}

// @Summary 用户登录
// @Description 输入账号密码以及验证码登录
// @Tags 注册登录
// @Accept json
// @Produce json
// @Param userInfo body models.LoginParams true "用户信息"
// @Success 200 {object} models.ResultCommon[models.LoginResult] "登录成功"
// @Failure 404 {object} models.ErrorResult "请求失败"
// @Failure 403 {object} models.ErrorResult "验证码错误"
// @Failure 402 {object} models.ErrorResult "用户名或密码错误"
// @Router /login [post]
func (l LoginAbout) Login(ctx *gin.Context) {
	var params models.LoginParams
	// 绑定json数据
	if err := ctx.ShouldBindJSON(&params); err != nil {
		ctx.JSON(http.StatusOK, &models.ErrorResult{
			Msg:    "登录失败",
			Code:   "400",
			Result: nil,
		})
		return
	}
	// 先校验验证码对不对
	if !utils.CaptVerify(params.Id, params.Code) {
		ctx.JSON(http.StatusOK, &models.ErrorResult{
			Msg:    "验证码错误",
			Code:   "400",
			Result: nil,
		})
		return
	}

	params.Password = utils.Sha256(params.Password)
	var user models.User
	models.DB.Where("account=? AND password=?", params.Account, params.Password).First(&user)
	if user.Id == 0 {
		ctx.JSON(http.StatusOK, &models.ErrorResult{
			Msg:    "用户名或密码错误",
			Code:   "400",
			Result: nil,
		})
	} else {
		// 查询该用户的角色
		var roleList []models.Role
		models.DB.Model(&models.Role{}).
			Joins("JOIN user_role On roles.id = user_role.role_id").
			Where("user_role.user_id = ? AND roles.is_delete = 0", user.Id).
			Find(&roleList)
		user.Role = roleList
		var userRole []models.UserRole
		models.DB.Table("user_role").Where("user_id = ?", user.Id).Find(&userRole)
		// 签发令牌
		token, _ := jwt.GenerateToken(jwt.UserInfo{
			Id:       user.Id,
			UserName: user.Username,
			Roles:    userRole,
		})
		// 返回结果
		result := models.LoginResult{
			Token:    token,
			UserInfo: user,
		}
		ctx.JSON(http.StatusOK, &models.ResultCommon[models.LoginResult]{
			Msg:    "登录成功",
			Code:   "200",
			Result: result,
		})
	}
}

// @Summary 生成验证码
// @Description 生成6位数字字母大小写混合图形验证码验证码
// @Tags 注册登录
// @Produce json
// @Success 200 {object} models.ResultCommon[models.CodeResult] "成功响应"
// @Failure 404 {object} models.ErrorResult "请求失败"
// @Router /imageCode [get]
func (l LoginAbout) CreateImageCode(ctx *gin.Context) {
	id, base64Str, err := utils.CreateImageCode()
	if err != nil {
		ctx.JSON(http.StatusOK, models.ErrorResult{
			Msg:    "获取失败",
			Code:   "400",
			Result: nil,
		})
	} else {
		result := models.CodeResult{
			Id:   id,
			Data: base64Str,
		}
		ctx.JSON(http.StatusOK, models.ResultCommon[models.CodeResult]{
			Msg:    "获取成功",
			Code:   "200",
			Result: result,
		})
	}
}
